package com.cn.utils;


import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.UUID;


/**
 * 文件上传
 *
 * @author 时间海 @github dulaiduwang003
 * @version 1.0
 */
@Component
@SuppressWarnings("all")
@Slf4j
public class UploadUtil {

//    @Value("${oss.ali-oss.endpoint}")
//    private String endpoint;
//
//    @Value("${oss.ali-oss.accessKey}")
//    private String accessKey;
//
//    @Value("${oss.ali-oss.secretKey}")
//    private String secretKey;
//
//    @Value("${oss.ali-oss.bucketName}")
//    private String bucketName;

    /**
     * 上传文件到minio
     *
     * @param file
     * @param path
     * @return
     */
    @Value("${oss.minio-oss.endpoint}")
    private String endpoint;

    @Value("${oss.minio-oss.accessKey}")
    private String accessKey;

    @Value("${oss.minio-oss.secretKey}")
    private String secretKey;

    @Value("${oss.minio-oss.bucketName}")
    private String bucketName;


//    public String uploadFile(final MultipartFile file, final String path) {
//
//        OSS ossClient = new OSSClientBuilder()
//                .build(endpoint, accessKey, secretKey);
//        try (InputStream inputStream = file.getInputStream()) {
//            String originalFileName = file.getOriginalFilename();
//
//            assert originalFileName != null;
//            String fileName;
//            fileName = UUID.randomUUID() + originalFileName.substring(originalFileName.lastIndexOf('.'));
//
//            String filePath = path + "/" + fileName;
//            ObjectMetadata objectMetadata = new ObjectMetadata();
//            objectMetadata.setContentType("image/png");
//            ossClient.putObject(bucketName, filePath, inputStream, objectMetadata);
//            return "/" + filePath;
//
//        } catch (IOException e) {
//            throw new OSSException();
//        } finally {
//            ossClient.shutdown();
//        }
//    }

    // 上传文件到minio
    public String uploadFile(final MultipartFile file, final String path) {
        log.info("调用方法【uploadFile】上传文件到minio");
        MinioClient ossClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        try (InputStream inputStream = file.getInputStream()) {
            String originalFileName = file.getOriginalFilename();

            assert originalFileName != null;
            String fileName;
            fileName = UUID.randomUUID() + originalFileName.substring(originalFileName.lastIndexOf('.'));

            String filePath = path + "/" + fileName;
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType("image/png");
//            ossClient.putObject(bucketName, filePath, inputStream, objectMetadata);
            ossClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(filePath)
                    .stream(inputStream, file.getSize(), -1)
                    .build());
            log.info("上传文件位置：%s".format(filePath));
            return "/" + filePath;

        } catch (Exception e) {
            throw new OSSException();
        }
    }

    public String uploadImageFromUrl(String imageUrl, String path) {
        log.info("调用方法【uploadImageFromUrl】上传文件到minio");
        MinioClient ossClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        try {
            // 生成随机的图片名称
            String fileName = path + "/" + UUID.randomUUID().toString() + ".png";


            // 通过URL下载网络图片到本地
            URL url = new URL(imageUrl);
            InputStream inputStream = url.openStream();
            // 上传图片到OSS
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType("image/jpg");
//            ossClient.putObject(bucketName, fileName, inputStream, objectMetadata);
            ossClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(inputStream, inputStream.read(), -1)
                    .build());
            return "/" + fileName;
        } catch (Exception e) {
            throw new OSSException();
        }
    }

    public String uploadBase64Image(final String base64Image, String path) {
        log.info("调用方法【uploadBase64Image】上传文件到minio");
        MinioClient ossClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
//        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
        try {
            // 使用UUID生成新的文件名
            String fileName = path + "/" + UUID.randomUUID().toString() + ".jpg";
            // 将Base64图片转换为字节数组
            byte[] imageBytes = Base64.getDecoder().decode(base64Image);
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType("image/jpg");
            // 创建PutObjectRequest对象并上传图片
//            PutObjectRequest request = new PutObjectRequest(bucketName, fileName, new ByteArrayInputStream(imageBytes), objectMetadata);
//            ossClient.putObject(request);
            ossClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(new ByteArrayInputStream(imageBytes), imageBytes.length, -1)
                    .build());
            return "/" + fileName;
        } catch (Exception e) {
            throw new OSSException();
        }

    }

    public void deletedFile(final String path) {
        log.info("调用方法【uploadBase64Image】上传文件到minio");
        MinioClient ossClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        try {

            if (path.startsWith("/")) {
//                ossClient.deleteObject(bucketName, path.substring(1));
                ossClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path.substring(1)).build());
            } else {
                ossClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path).build());
            }
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        }
    }

}
